package api

import (
	"config-client-v1/init/global"
	"config-client-v1/model"
	"config-client-v1/utils/tools"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/xuri/excelize/v2"
	"path/filepath"
)

type ExcelController struct {
}

func (con ExcelController) ModelReport(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		IDS string `json:"ids"` // 模型ID,多个用逗号隔开
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	ids := tools.StrToIntSlice(param.IDS)
	if len(ids) == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "请选择要导出的模型",
		})
		return
	}
	old := &model.User{}
	exist, err := old.Exists(userToken.Uid)
	if !exist {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "Uid未找到",
			"data":    err,
		})
		return
	}
	list := make([]*model.FSModel, 0)
	err = model.DB.Preload("FSEquipInfo").Where("id in ?", ids).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	if len(list) == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "未找到相关模型",
		})
		return
	}
	moduleType := list[0].ModuleType
	for _, id := range ids {
		matched := false
		for _, module := range list {
			if id == module.ID {
				matched = true
				if moduleType != module.ModuleType {
					ctx.JSON(200, gin.H{
						"code":    2,
						"message": "请选择相同类型的模型",
					})
					return
				}
				break
			}
		}
		if !matched {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "部分模型未找到",
			})
		}
	}
	for _, row := range list {
		if row.FSEquipInfo != nil {
			row.FSName = row.FSEquipInfo.Name
			//fmt.Println("row.FSEquipInfo.Name = ", row.FSEquipInfo.Name)
			//row.FSEquipInfo = nil
		} else {
			row.FSName = "null"
		}
	}
	outputName := ""
	switch moduleType {
	case "泵组电磁阀":
		f := excelize.NewFile()
		sheetName := "Sheet1"
		index, _ := f.NewSheet(sheetName)
		f.SetActiveSheet(index)
		// 定义几种样式
		style, _ := f.NewStyle(&excelize.Style{
			Alignment: &excelize.Alignment{
				Horizontal: "center", // 水平居中
				Vertical:   "center", // 垂直居中
			},
			Border: []excelize.Border{
				{Type: "left", Color: "999999", Style: 1},   // 左边框：蓝色，粗线
				{Type: "right", Color: "999999", Style: 1},  // 右边框：蓝色，粗线
				{Type: "top", Color: "999999", Style: 1},    // 上边框：蓝色，粗线
				{Type: "bottom", Color: "999999", Style: 1}, // 下边框：蓝色，粗线
			},
		})
		styleHeader, _ := f.NewStyle(&excelize.Style{
			Alignment: &excelize.Alignment{
				Horizontal: "center", // 水平居中
				Vertical:   "center", // 垂直居中
			},
			Border: []excelize.Border{
				{Type: "left", Color: "999999", Style: 1},   // 左边框：蓝色，粗线
				{Type: "right", Color: "999999", Style: 1},  // 右边框：蓝色，粗线
				{Type: "top", Color: "999999", Style: 1},    // 上边框：蓝色，粗线
				{Type: "bottom", Color: "999999", Style: 1}, // 下边框：蓝色，粗线
			},
			Font: &excelize.Font{
				Bold:   true,     // 加粗
				Size:   14,       // 字体大小
				Color:  "0000FF", // 字体颜色（蓝色）
				Family: "Arial",  // 字体类型
			},
		})
		styleFooter, _ := f.NewStyle(&excelize.Style{
			Alignment: &excelize.Alignment{
				Horizontal: "left",   // 水平居中
				Vertical:   "center", // 垂直居中
			},
			Border: []excelize.Border{
				{Type: "left", Color: "999999", Style: 1},   // 左边框：蓝色，粗线
				{Type: "right", Color: "999999", Style: 1},  // 右边框：蓝色，粗线
				{Type: "top", Color: "999999", Style: 1},    // 上边框：蓝色，粗线
				{Type: "bottom", Color: "999999", Style: 1}, // 下边框：蓝色，粗线
			},
		})
		// 设置列宽
		_ = f.SetColWidth(sheetName, fmt.Sprintf("%c", 'B'), fmt.Sprintf("%c", 'B'+4), 20.0)
		_ = f.SetColWidth(sheetName, fmt.Sprintf("%c", 'G'), fmt.Sprintf("%c", 'G'+4), 20.0)
		// 顶部标题合并行, 并设置行高, 填值
		_ = f.MergeCell(sheetName, fmt.Sprintf("B%d", 1), fmt.Sprintf("K%d", 1))
		_ = f.SetRowHeight(sheetName, 1, 30.0)
		_ = f.SetCellValue(sheetName, fmt.Sprintf("B1"), moduleType+"报表")

		blockStartRowNum := 2
		for i, row := range list {
			startCol := 'B'
			rowEnd := false
			if i%2 == 0 { // 左边
				startCol = 'B'
			} else { // 右边
				startCol = 'G'
				rowEnd = true
			}
			_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("%c%d", startCol+4, blockStartRowNum))
			_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+1), fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+1))
			_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+2), fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+2))

			_ = f.SetRowHeight(sheetName, blockStartRowNum, 30.0)
			_ = f.SetRowHeight(sheetName, blockStartRowNum+1, 20.0)

			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("%s-%s", row.FSName, row.ModuleName))

			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+1), fmt.Sprintf("泵前压力"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+1), fmt.Sprintf("泵前电磁阀"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+1), fmt.Sprintf("前级泵"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+1), fmt.Sprintf("罗茨泵"))

			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+2), fmt.Sprintf("YL"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+2), fmt.Sprintf("DCF"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+2), fmt.Sprintf("QJB"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+2), fmt.Sprintf("LCB"))

			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+3), fmt.Sprintf("变量YL数值"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+3), fmt.Sprintf("变量YL单位"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+3), fmt.Sprintf("开状态"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+3), fmt.Sprintf("启动"))
			_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+3), fmt.Sprintf("停止"))

			if err := f.SetCellStyle(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+3), style); err != nil {
				ctx.JSON(200, gin.H{
					"code":    1,
					"message": err.Error(),
					"data":    "设置excel样式失败",
				})
				return
			}

			if i == len(list)-1 {
				blockStartRowNum += 4
			} else {
				if rowEnd {
					blockStartRowNum += 4
				}
			}
		}
		//blockStartRowNum--
		// 合并底部
		_ = f.MergeCell(sheetName, fmt.Sprintf("B%d", blockStartRowNum), fmt.Sprintf("F%d", blockStartRowNum))
		_ = f.MergeCell(sheetName, fmt.Sprintf("G%d", blockStartRowNum), fmt.Sprintf("K%d", blockStartRowNum))
		// 底部设置行高
		_ = f.SetRowHeight(sheetName, blockStartRowNum, 30.0)
		// 底部填值
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", 'B', blockStartRowNum), fmt.Sprintf("打印时间：%s", tools.GetNow()))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", 'G', blockStartRowNum), fmt.Sprintf("试验人员：%s", old.Realname))
		if err := f.SetCellStyle(sheetName, fmt.Sprintf("%c%d", 'B', 1), fmt.Sprintf("%c%d", 'B'+9, 1), styleHeader); err != nil {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": err.Error(),
				"data":    "设置excel样式失败",
			})
			return
		}
		if err := f.SetCellStyle(sheetName, fmt.Sprintf("%c%d", 'B', blockStartRowNum), fmt.Sprintf("%c%d", 'B'+9, blockStartRowNum), styleFooter); err != nil {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": err.Error(),
				"data":    "设置excel样式失败",
			})
			return
		}

		// 直接下载
		//con.Write(ctx, "download.xlsx", f)
		f.SetActiveSheet(index)
		outputName = "tmp/" + moduleType + "-" + tools.GetTimestamp() + "报表.xlsx"
		outputFile := filepath.Join(global.StaticPath, outputName)
		tools.CreateDir(filepath.Dir(outputFile))
		if err = f.SaveAs(outputFile); err != nil {
			ctx.JSON(200, gin.H{
				"code":    2,
				"message": "保存excel文件失败",
				"data":    map[string]interface{}{},
			})
			return
		}
	case "增压泵电磁阀":
		fallthrough
	case "电调阀":
		fallthrough
	case "压力电磁阀":
		fallthrough
	default:
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "暂不支持的模型类型",
			"data":    map[string]interface{}{},
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"url": outputName,
		},
	})
	//for _, row := range list {
	//	if row.FSEquipInfo != nil {
	//		row.FSName = row.FSEquipInfo.Name
	//		row.FSEquipInfo = nil
	//	}
	//	switch row.ModuleType {
	//	case "泵组电磁阀":
	//		content := model.BengzuModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "增压泵电磁阀":
	//		content := model.ZengyaModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "电调阀":
	//		content := model.DiantiaoSVModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "压力电磁阀":
	//		content := model.PressureSVModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "电源控制":
	//		content := model.PowerModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "电源状态":
	//		content := model.PowerStateModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "模态采集":
	//		content := model.ModeCollectModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	case "故障诊断":
	//		content := model.DiagModel{}
	//		_ = json.Unmarshal([]byte(row.JsonDetail), &content)
	//		row.Content = content
	//	}
	//	row.JsonDetail = ""
	//}

	//tools.SliceReverse(&list)

}

func (con ExcelController) Write(ctx *gin.Context, fileName string, file *excelize.File) {
	ctx.Writer.Header().Add("Content-Type", "application/octet-stream")
	ctx.Writer.Header().Add("Content-disposition", "attachment;filename="+fileName)
	ctx.Writer.Header().Add("Content-Transfer-Encoding", "binary")
	_ = file.Write(ctx.Writer)
}

func (con ExcelController) Excel(ctx *gin.Context) {
	f := excelize.NewFile()
	//index := f.NewSheet("Sheet2")
	sheetName := "Sheet1"
	// 定义居中对齐的样式
	style, _ := f.NewStyle(&excelize.Style{
		Alignment: &excelize.Alignment{
			Horizontal: "center", // 水平居中
			Vertical:   "center", // 垂直居中
		},
		Border: []excelize.Border{
			{Type: "left", Color: "999999", Style: 1},   // 左边框：蓝色，粗线
			{Type: "right", Color: "999999", Style: 1},  // 右边框：蓝色，粗线
			{Type: "top", Color: "999999", Style: 1},    // 上边框：蓝色，粗线
			{Type: "bottom", Color: "999999", Style: 1}, // 下边框：蓝色，粗线
		},
	})

	_ = f.SetColWidth(sheetName, "B", "F", 20.0)
	_ = f.SetColWidth(sheetName, "H", "L", 20.0)
	// 定义边框样式

	blockStartRowNum := 2
	//blockEndRowNum := blockStartRowNum + 3
	modelNum := 5
	for i := 1; i <= modelNum; i++ {
		startCol := 'B'
		rowEnd := false
		if i%2 == 1 { // 奇数左边
			startCol = 'B'
		} else { // 偶数右边 H~L
			startCol = 'H'
			rowEnd = true
		}
		_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("%c%d", startCol+4, blockStartRowNum))
		_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+1), fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+1))
		_ = f.MergeCell(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+2), fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+2))

		_ = f.SetRowHeight(sheetName, blockStartRowNum, 30.0)
		_ = f.SetRowHeight(sheetName, blockStartRowNum+1, 20.0)

		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("泵组电磁阀%02d", i))

		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+1), fmt.Sprintf("泵前压力"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+1), fmt.Sprintf("泵前电磁阀"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+1), fmt.Sprintf("前级泵"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+1), fmt.Sprintf("罗茨泵"))

		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+2), fmt.Sprintf("YL"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+2), fmt.Sprintf("DCF"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+2), fmt.Sprintf("QJB"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+2), fmt.Sprintf("LCB"))

		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum+3), fmt.Sprintf("变量YL数值"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+1, blockStartRowNum+3), fmt.Sprintf("变量YL单位"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+2, blockStartRowNum+3), fmt.Sprintf("开状态"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+3, blockStartRowNum+3), fmt.Sprintf("启动"))
		_ = f.SetCellValue(sheetName, fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+3), fmt.Sprintf("停止"))

		if err := f.SetCellStyle(sheetName, fmt.Sprintf("%c%d", startCol, blockStartRowNum), fmt.Sprintf("%c%d", startCol+4, blockStartRowNum+3), style); err != nil {
			ctx.JSON(200, gin.H{
				"code":    1,
				"message": err.Error(),
				"data":    "设置excel样式失败",
			})
			return
		}

		if rowEnd {
			blockStartRowNum += 5
		}
	}

	//ctx.String(200, "OK")
	//return
	// 直接下载
	con.Write(ctx, "download.xlsx", f)
	// 保存到文件
	//f.SetActiveSheet(index)
	//if err = f.SaveAs("book1.xlsx"); err != nil {
	//	ctx.JSON(200, gin.H{
	//		"data": err.Error(),
	//	})
	//	return
	//}
	//ctx.JSON(200, gin.H{
	//	"data": "success",
	//})
}

func (con ExcelController) PageReportSave(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		PageID      int    `json:"page_id" binding:"required"`
		PageName    string `json:"page_name" binding:"required,max=100"`
		Base64Image string `json:"base64_image" binding:"required"`
		Operator    string `json:"operator" binding:"required"`
		OperateTime string `json:"operate_time" binding:"required"`
		ReportTime  string `json:"report_time" binding:"required"`
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	page := &model.Page{}

	err = model.DB.Where("project_id = ? AND id = ?", userToken.ProjectID, param.PageID).Limit(1).Find(page).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}

	if page.ID == 0 {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数 page_id",
			"data":    "",
		})
		return
	}

	now := tools.GetNow()
	data := model.PageReportLog{}
	data.ProjectID = userToken.ProjectID
	data.UID = userToken.Uid
	data.PageID = param.PageID
	data.PageName = param.PageName
	data.Operator = param.Operator
	data.OperateTime = param.OperateTime
	data.ReportTime = param.ReportTime
	data.Base64Image = param.Base64Image
	data.CreateTime = &now

	err = model.DB.Create(&data).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data":    map[string]interface{}{},
	})

}

func (con ExcelController) PageReportList(ctx *gin.Context) {
	userToken := GetUserToken(ctx)
	param := struct {
		PageID   int    `json:"page_id"`
		PageName string `json:"page_name"`
		model.QueryData
	}{}
	err := ctx.ShouldBindBodyWith(&param, binding.JSON)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    2,
			"message": "无效的参数",
			"data":    err.Error(),
		})
		return
	}
	tx := model.DB.Where("project_id = ?", userToken.ProjectID)
	if param.PageID != 0 {
		tx.Where("page_id = ?", param.PageID)
	}
	if param.PageName != "" {
		tx.Where("name like ?", "%"+param.PageName+"%")
	}
	var count int64
	list := make([]model.PageReportLog, 0)
	err = tx.Model(&model.PageReportLog{}).Count(&count).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	err = tx.Order("id ASC").Offset(param.StartPage()).Limit(param.PageSize).Find(&list).Error
	if err != nil {
		ctx.JSON(200, gin.H{
			"code":    6,
			"message": err.Error(),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code":    0,
		"message": "success",
		"data": map[string]interface{}{
			"list":  list,
			"count": count,
		},
	})
}
